<template>
  <div>
    <vxe-pulldown
      ref="pulldownRef"
      style="width: 100%"
      popup-class-name="ad-choose-list-dropdown"
      v-bind="getDropdownProps"
      @hide-panel="hidePanelEvent"
    >
      <template #default>
        <vxe-input
          ref="inputRef"
          style="width: 100%"
          v-model="inputValue"
          v-bind="getInputProps"
          @keyup="keyupEvent"
          @focus="focusEvent"
          @blur="blurEvent"
          @suffix-click="suffixClick"
          @input="inputEvent"
        >
          <template #suffix>
            <vxe-button type="text">
              <template #icon>
                <BarsOutlined />
              </template>
            </vxe-button>
          </template>
        </vxe-input>
      </template>
      <template #dropdown>
        <div
          class="ad-choose-list-bodydown"
          :style="`width:${dropdownWidth}px;height:${dropdownHeight}px`"
        >
          <vxe-grid
            ref="tableRef"
            :stripe="false"
            :border="true"
            headerAlign="center"
            v-bind="getVxeGridProps"
            auto-resize
            height="auto"
            id="ad-choose-list-pulldown-table"
            :showOverflow="'tooltip'"
            :row-config="{ isCurrent: true, isHover: true }"
            :column-config="{ resizable: true }"
            :loading="loading"
            :data="tableData"
            @cell-dblclick="cellDbClickEvent"
          />
        </div>
      </template>
    </vxe-pulldown>

    <!-- <AdChooseListDialog @register="registerDialog" v-bind="getDialogProps" /> -->
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted, onUnmounted, toRefs, watchEffect, watch, computed } from 'vue';
  import {
    VxeGridEvents,
    VxeInputDefines,
    VxePulldownInstance,
    VxeInputInstance,
    VxeTableInstance,
    VxePulldown,
    VxeInput,
    VxeButton,
    VxeGrid,
    VxeTablePropTypes,
  } from 'vxe-table';
  import { BarsOutlined } from '@ant-design/icons-vue';
  import { debounce } from 'lodash-es';

  import { isFunction } from '@/utils/is';
  import { PageRequest, FilterRule } from '@/utils/common/types';

  import { ReturnMethods } from '@/components/AdVxeModal';

  // import { useModal } from '@/components/AdVxeModal';

  import { FilterOperateEnum } from '@/enums/filterOperateEnum';

  import { adChooseListProps } from './props';
  import { castToVxeSize } from './types';
  // import AdChooseListDialog from './dialog.vue';

  defineOptions({ name: 'AdChooseList' });

  const props = defineProps({
    ...adChooseListProps,
    dialogMethods: {
      type: Object as PropType<ReturnMethods>,
      default: undefined,
    },
  });
  const emit = defineEmits(['update:value', 'change']);

  // const [registerDialog, dialogMethods] = useModal();

  /** 下拉容器实例 */
  const pulldownRef = ref<VxePulldownInstance>();
  /** 输入框实例 */
  const inputRef = ref<VxeInputInstance>();
  /** 下拉表格实例 */
  const tableRef = ref<VxeTableInstance>();
  /** 加载状态 */
  const loading = ref(false);
  /** 表格数据 */
  const tableData = ref<VxeTablePropTypes.Data>(props.data || []);

  /** 输入框的值 */
  const inputValue = ref(props.value || '');
  /** 输入框参数 */
  const inputField = computed(() => props.field);
  /** 输入框数据验证 */
  const inputValidate = computed(() => props.validate);
  /** 输入框参数 */
  const getInputProps = computed(() => {
    return {
      size: castToVxeSize(props.size),
      placeholder: props.placeholder,
      disabled: props.disabled,
    };
  });

  const { dropdownWidth, dropdownHeight } = toRefs(props);
  /** 下拉面板参数 */
  const getDropdownProps = computed(() => {
    return {
      size: castToVxeSize(props.dropdownSize),
      disabled: props.disabled === true ? props.disabled : props.dropdownDisabled,
      placement: props.dropdownPlacement,
      destroyOnClose: props.dropdownDestroyOnClose,
      transfer: props.dropdownTransfer,
    };
  });
  /** 下拉面板表格参数 */
  const getVxeGridProps = computed(() => {
    return {
      size: castToVxeSize(props.dropdownTableSize),
      columns: props.columns,
    };
  });

  // /** 对话框窗体参数 */
  // const getDialogProps = computed(() => {
  //   return {
  //     /** 宽度 */
  //     width: props.dialogWidth,
  //     /** 标题 */
  //     title: props.dialogTitle,
  //     /** 表格尺寸 */
  //     tableSize: props.dialogTableSize,
  //     /** 数据 */
  //     data: props.data,
  //     /** 数据请求接口 */
  //     api: props.api,
  //     /** 额外的请求参数 */
  //     searchInfo: props.searchInfo,
  //     /** 表格列配置 */
  //     columns: props.columns,
  //     /** 是否多选 */
  //     multiple: props.dialogMultiple,
  //     /** 选择函数，当返回值为 false 时阻止弹出关闭。 */
  //     selectFn: props.selectFn,
  //   };
  // });

  /** 请求表格数据 */
  async function fetchTableData() {
    const { api } = props;
    if (api && isFunction(api)) {
      try {
        loading.value = true;

        const request = new PageRequest();
        if (props.searchInfo) {
          request.FilterGroup = props.searchInfo;
        }
        const filterField = props.filterField || inputField.value;
        if (filterField && inputValue.value) {
          let filterOperate: FilterOperateEnum = props.filterOperate;
          if (!filterOperate) {
            const column = props.columns.find((col) => col.field === filterField);
            switch (column?.dataType) {
              case 'enum':
              case 'integer':
              case 'number':
              case 'quantity':
              case 'price':
              case 'amount':
              case 'rate':
              case 'percentage':
              case 'measure':
                filterOperate = FilterOperateEnum.Equal;
                break;
              case 'string':
              case 'text':
              case 'password':
              case 'email':
              case 'mobile':
              case 'url':
              case 'ipv4':
              case 'ipv6':
              case 'idcard':
                filterOperate = FilterOperateEnum.Contains;
                break;
              case 'guid':
                filterOperate = FilterOperateEnum.Equal;
                break;
              case 'boolean':
              case 'datetime':
              case 'time':
              case 'array':
                filterOperate = FilterOperateEnum.Equal;
                break;
            }
          }

          request.FilterGroup.Rules.push(
            new FilterRule(filterField, inputValue.value, filterOperate),
          );
        }
        const pageData = await api(request);
        tableData.value = pageData.Rows;
      } finally {
        loading.value = false;
      }
    }
    return tableData.value;
  }

  watchEffect(() => {
    inputValue.value = props.value || '';
    tableData.value = props.data || [];
  });
  watch(
    () => inputValue.value,
    (v: string) => {
      emit('update:value', v);
    },
  );

  /** 在下拉面板被触发隐藏时触发该事件 */
  const hidePanelEvent = async () => {
    const row = tableRef.value?.getCurrentRecord();
    if (row) {
      if (inputField.value) {
        inputValue.value = row[inputField.value];
      }
      emitChange(row);
    }
    await inputRef.value?.focus();
  };

  /** 在键盘输入按下弹起时触发该事件 */
  const keyupEvent = () => {
    // loading.value = true;
    // setTimeout(() => {
    //   loading.value = false;
    //   if (inputValue.value) {
    //     tableData.value = tableList.value.filter((row) => row.name.indexOf(inputValue.value) > -1);
    //   } else {
    //     tableData.value = tableList.value.slice(0);
    //   }
    // }, 100);
  };
  /** 在输入框聚焦时触发该事件 */
  const focusEvent = async () => {
    // await pulldownRef.value?.showPanel();
    // await fetchTableData();
  };
  /** 在输入框失焦时触发该事件 */
  const blurEvent = async (params: VxeInputDefines.BlurEventParams) => {
    const { value } = params;
    if (inputValidate.value && value) {
      const tbData = tableData.value;
      if (tbData?.length === 1 && inputField.value) {
        const row = tbData[0];
        inputValue.value = row[inputField.value];
        emitChange(row);
      } else {
        await inputRef.value?.focus();
        // if ($event['relatedTarget']) {
        //   inputValue.value = '';
        // }
        // await $input.select();
      }
    }
  };
  /** 在点击尾部图标时触发该事件 */
  const suffixClick = async () => {
    // await pulldownRef.value?.togglePanel();
    if (inputValue.value) {
      await fetchTableData();
      const tbData = tableData.value;
      if (!(tbData?.length === 1)) {
        inputValue.value = '';
        emitChange({});
      }
    }
    await pulldownRef.value?.hidePanel();
    props.dialogMethods?.openModal(true, {
      selectFn: props?.selectFn,
      props: props,
    });
  };
  /** 在键盘输入时触发该事件，防抖函数处理。 */
  const inputEvent = debounce(async (_params: any) => {
    await pulldownRef.value?.showPanel();
    await fetchTableData();
  }, 500);
  /** 单元格双击事件 */
  const cellDbClickEvent: VxeGridEvents.CellDblclick = async ({ row }) => {
    if (inputField.value) {
      inputValue.value = row[inputField.value];
    }
    emitChange(row);
    await pulldownRef.value?.hidePanel();
    await inputRef.value?.focus();
  };

  /** 触发数据更改事件 */
  function emitChange(record: Recordable) {
    const { changeFn } = props;
    const data = { field: inputField.value, value: inputValue.value, record };
    if (changeFn && isFunction(changeFn)) {
      changeFn(data);
    }
    emit('change', data);
  }

  onMounted(() => {
    keyupEvent();
  });
  onUnmounted(() => {
    // setSelectFn(props.uid, undefined);
  });
</script>

<style scoped lang="scss">
  .vxe-pulldown--content {
    width: 100%;
  }

  .ad-choose-list-dropdown {
    // background-color: #fff;
    box-shadow: 0 0 6px 2px rgb(0 0 0 / 10%);

    .ad-choose-list-bodydown {
      width: 600px;
      height: 300px;
    }

    // .ad-choose-list-footdown {
    //   border-top: 1px solid #e8eaec;
    // }
  }
</style>
